<?php

namespace app\uniapp\service;

use app\common\exception\MiException;
use app\common\service\CommonSiteConfigService;
use app\common\validate\site\UserOauthValidate;
use app\common\validate\site\UserValidate;
use app\extend\MiCurl;
use app\model\site\User;
use app\model\site\UserOauth;
use app\model\site\UserPointsLog;
use app\service\wx\WxMpService;
use app\uniapp\service\traits\InstanceTrait;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Db;

class UserService extends UniBaseService
{
    use InstanceTrait;

    function initialize()
    {
        $this->model = new User();
    }

    function formatData(array $data): array
    {
        return $data;
    }

    /**
     * 通过第三方唯一标识id查询用户信息
     * @param $oauthId
     * @param $oauthType
     * @return mixed
     */
    public function getUserIdByOauthId($oauthId, $oauthType): mixed
    {
        return UserOauth::where('oauth_id', $oauthId)
            ->where('oauth_type', $oauthType)
            ->where('site_id', $this->siteId)
            ->value('user_id');
    }

    /**
     * 通过微信小程序的openid验证是否登录
     * @param $code
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function checkRegisterByPlatForm($code): bool
    {
        $platform = getUniPlatform();
        $userId = false;
        if ($platform == 'mp-weixin'){
            $config = $mpConfig = CommonSiteConfigService::instance()->getConfigValue($this->siteId, CommonSiteConfigService::WX_MP);
            $session = WxMpService::instance($config)->getWxMpSession($code);
            // 判断openid是否存在
            $userId = UserService::instance()->getUserIdByOauthId($session['openid'], getUniPlatform());
        }
        return (bool)$userId;
    }

    public function updateLoginUser(User $user, $post): User
    {
        if ($mobile = $post['mobile']??'') $user->mobile = $mobile;
        $user->login_time = time();
        $user->login_ip = request()->ip();
        $user->login_platform = getUniPlatform();
        $user->login_count = $user->count + 1;
        $user->save();
        return $user;
    }

    /**
     * @throws Exception
     */
    public function createLoginUser($data, $oauth=[]): User
    {
        $data['register_platform'] = getUniPlatform();
        try {
            // 验证用户表
            validate(UserValidate::class)->scene('oauthAdd')->check($data);
            // 验证三方表
            if (count($oauth) > 0){
                validate(UserOauthValidate::class)->scene('togetherAdd')->check($oauth);
            }
        }catch (ValidateException $e){
            throw new MiException($e->getError());
        }
        $loginConfig = CommonSiteConfigService::instance()->getConfigValue(UniAuthService::instance()->getSiteId(), CommonSiteConfigService::LOGIN);
        $user = new User();
        // 启动事务
        Db::startTrans();
        try {
            foreach ($data as $k=>$v){
                $user->$k = $v;
            }
            $user->login_time = time();
            $user->login_ip = request()->ip();
            $user->login_platform = getUniPlatform();
            $user->login_count = 1;

            if (count($oauth) > 0){
                $oauthObj = new UserOauth();
                foreach ($oauth as $k => $v){
                    $oauthObj->$k = $v;
                }
                $user->oauth = $oauthObj;
                $user->together(['oauth'])->save();
            }else{
                $user->save();
            }

            // 赠送优惠券
            if ($loginConfig['give_coupon_id']){
                UserCouponService::instance()->createByCouponId($loginConfig['give_coupon_id'], $user->id);
            }
            // 赠送积分
            if ($loginConfig['give_points']){
                User::update([
                    'points' => $user->points + $loginConfig['give_points'],
                ],[
                    'id' => $user->id,
                ]);
//                $user->points = $user->points + $loginConfig['give_points'];
//                $user->save();
                // 创建积分记录
                UserPointsLog::create([
                    'site_id' => UniAuthService::instance()->getSiteId(),
                    'user_id' => $user->id,
                    'price' => 0,
                    'amount' => $loginConfig['give_points'],
                    'rel_model' => '',
                    'rel_id' => 0,
                    'change_type' =>2,
                    'note' => "注册赠送"
                ]);
            }

            // 提交事务
            Db::commit();
        }  catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            throw  $e;
        }

        return $user;
    }


    /**
     * 下载微信头像到本地
     * @throws Exception
     */
    public function  downLoadWxAvatar($wxAvatar): string
    {

        $res = MiCurl::instance()->get($wxAvatar)->toJson();

        $savename = md5($wxAvatar).'.png';

        $date = date('Ymd');
        $public_path = str_replace("\\",'/',public_path());
        $uploadDir = $public_path.'uploads/'.$date;
//
        $path = str_replace("\\","/",root_path().'public/uploads/'.$date.'/');
        // 创建上传目录
        if (!file_exists($uploadDir)) {
            @mkdir($uploadDir);
        }


        $resource = fopen($path . $savename, 'a');
        fwrite($resource, $res);
        fclose($resource);

        return '/uploads/'.$date.'/'.$savename;

    }

    /*
     * 个人专属小程序码
     */
    /**
     * @throws MiException
     */
    public function wxMpQrcode($userId): string
    {

        $savename = "own_qrcode.png";
        $baseStr = "/uploads/user/{$userId}";
        // 完成的文件存储路径 不包含文件名
        $upPath = public_path($baseStr);
        // url访问文件路径
        $urlPath = "{$baseStr}/{$savename}";
        // 包含文件名的完整文件存储路径
        $fullPath = $upPath.$savename;
//        $fullPath =  str_replace("\\","/",ROOT_PATH."/uploads/{$user->id}/");

        //        $path 小程序页面路径 格式：pages/index/index
        $page = 'pages/index/index';
        //  $scene 小程序页面参数 格式：参数1/参数1的值*参数2/参数2的值 （用“*”或者其他符号分割，小程序用decodeURIComponent获取）
        //  $scene 不要用“&”分割，也不要用“=”赋值，会有bug，
        $scene = "share_uid/{$userId}";
        $config = CommonSiteConfigService::instance()->getConfigValue($this->siteId, CommonSiteConfigService::WX_MP);
        $res = WxMpService::instance($config)->getUnlimitedQRCode([
            'scene' => $scene,
            'page'  => $page,
            'width' => 600,
//            'env_version' => 'develop',     // 开发版
        ]);
        // 保存小程序码到文件
        if(!is_dir($upPath)){
            mkdir($upPath,0755,true);
        }
        $file = fopen($fullPath,"w");
        fwrite($file,$res);
        fclose($file);
        return $urlPath;
    }



}
